home *** CD-ROM | disk | FTP | other *** search
/ Aminet 45 / Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso / Aminet / game / role / ldmud-3.2-bin.lha / mud / doc / driver / codestyle next >
Text File  |  2000-04-16  |  8KB  |  242 lines

  1.     The LPMud gamedriver is by nature the result of the cooperative work
  2.     of multiple programmers, often separated by large oceans and years
  3.     of time. In order to keep the appearance of the driver source consistent
  4.     (and with that maintainable), the following guidelines should be followed
  5.     for all code contributions.
  6.  
  7.     For a quick start in how good driver source should look like, take
  8.     a look at comm.{c,h}, object.{c,h} and mapping.{c.h}.
  9.  
  10.     The guidelines have a strong emphasis on code layout and commenting,
  11.     stemming from the fact that proper layout and comments gave the
  12.     incentive for LDMud in the first place. Right now, 50% of all lines
  13.     are comments, and that is a Good Thing.
  14.  
  15.  
  16. Language
  17. --------
  18.     The language is ISO Standard C (also known as 'C89' or 'ANSI C').
  19.     Common compiler extensions or features from the new C99 standard are
  20.     permitted if their addition is transparent for other C89 compilers.
  21.     For example: the 'inline' keyword permitted through the use of the
  22.     INLINE macro; so are the Metrowerks-pragmas and GNU-attributes. Not
  23.     permitted are GNU's local functions.
  24.  
  25.     System/Platform specifics are to be detected by the configure script
  26.     and provided with transparent implementations in port.{c,h} (or for
  27.     module-specific dependencies in the respective modules).
  28.  
  29.     Adherence to the Standard has the following implications:
  30.  
  31.      - All functions must be fully prototyped.
  32.      - Standard types like size_t, ssize_t or ptrdiff_t are to be used
  33.        whereever possible.
  34.      - Unixisms like
  35.          {
  36.            a = malloc(20);
  37.            b = malloc(20);
  38.            c = b-a;
  39.          }
  40.        are not legal and shouldn't be used.
  41.      - Don't make assumptions about the size of the base types (e.g. 
  42.        a char might have more than 8 bits). If such an assumption
  43.        is unavoidable, comment it clearly and if possible add a test
  44.        to raise a compile or runtime error if the assumption is not met.
  45.  
  46.  
  47. Style
  48. -----
  49.     All modules (.c-files) have to have their interface in an accompaning
  50.     .h-file. The header file must be guarded against repeated inclusion
  51.     with the normal
  52.         #ifndef HEADERNAME_H
  53.         #define HEADERNAME_H 1
  54.           ...
  55.         #endif /* HEADERNAME_H */
  56.     construct. To use a module, its headerfile must be included - no 'extern'
  57.     declarations.
  58.  
  59.     Every module must include "drivers.h" which in turn includes the
  60.     portability headers and provides common defines.
  61.  
  62.     Use the driver provided types and macros like BOOL or p_int.
  63.  
  64.     Code should be written defensively and readable. This is not the IOCCC.
  65.  
  66.     No magic numbers - use #defines to give them names.
  67.  
  68.     Add sanity checks where useful. If the checks are costly, enclose
  69.     them in a #ifdef DEBUG...#endif bracket.
  70.  
  71.     Comment questionable code or opportunities for possible extensions with a
  72.     'TODO: ...' comment. For multiline comments, use 'TODO::' on the second
  73.     and following lines (this makes reading a grep easier).
  74.  
  75.     Comment temporary debug code with a 'DEBUG:' comment. Similar, debug
  76.     output should always begin with 'DEBUG:'.
  77.  
  78.     Variable identifiers should start with a lowercase letter, function
  79.     identifiers may start with upper or lowercase, constant identifiers
  80.     should start with an uppercase letter. Macro identifiers should be
  81.     all UPPERCASE, other identifiers may be under_scored or SkudlyCaps.
  82.     Hungarian notation is accepted only in a very light form: pFoo for
  83.     pointers, ppFoo for pointer to pointers, iFoo for integer types, 
  84.     sFoo for string pointers, aFoo for complex types - you get the
  85.     idea. But no alpzsFoo and friends.
  86.  
  87.     f_xxx() function names are reserved for efun implementations.
  88.     typedef'd typenames should end in _t (e.g. 'mapping_t'), struct
  89.     names should end in _s (e.g. 'struct instrs_s').
  90.  
  91.     Indentation is 4 spaces per level. No tab characters anywhere!
  92.  
  93.     The indentation style is a variant of the 'Allman style':
  94.  
  95.         if (foo)
  96.         {
  97.             ...body...
  98.         } /* if (foo) */
  99.  
  100.     Note the comment at the closing brace!
  101.  
  102.     One line bodies may be written as
  103.  
  104.         if (foo) body;
  105.  
  106.     or
  107.  
  108.         if (foo)
  109.             body;
  110.  
  111.     _if_ it improves the readability.
  112.  
  113.     Similar, the typical layout of a function is:
  114.  
  115.         static int
  116.         function_name ( arg1 , arg2)
  117.         {
  118.             ....
  119.         } /* function_name() */
  120.  
  121.     If an expression (argument list, ...) extends over several, the first
  122.     literal element on a line should be an operator or syntactical marker:
  123.  
  124.         if (condition1
  125.          && (   condition2
  126.              || condition3)
  127.            )
  128.  
  129.         printf( "..."
  130.               , arg1, arg2, arg3
  131.               );
  132.  
  133.     Be generous with whitespace - both horizontal and vertical.
  134.  
  135.     [ The reasoning behind this style is to use the language elements
  136.       to create strong visual structures for the eyes to follow. By doing so,
  137.       the structure of the program becomes obvious without much
  138.       conscious thought.
  139.     ]
  140.  
  141.  
  142. Commenting
  143. ----------
  144.     The comments also follow the idea of giving strong visual clues of
  145.     how the program is structured.
  146.  
  147.     Horizontal lines should be created as
  148.  
  149.         /*------...-------*/
  150.         /*======...=======*/
  151.         /* - - -... - - - */
  152.  
  153.     The '---' line is the normal separator between the components of a
  154.     source file (includes, variable declarations, macro declarations,
  155.     the separate functions). The '===' line can be used to separate
  156.     larger sections of a source file (e.g. the lowlevel routines from
  157.     the efun implementations). '- -' lines, which usally span less than
  158.     the whole line, can be used to subdivide large functions (though then
  159.     it's often better to split the function into several small ones).
  160.  
  161.     A '***' line is reserved for the end of every source file.
  162.  
  163.     A '/* --- Subsection --- */' is also good to separate subsections.
  164.  
  165.     Vertical lines are to be constructed as
  166.  
  167.       /*
  168.        *
  169.        */
  170.  
  171.     No box comments.
  172.  
  173.     Every function must have a head comment explaining the meaning
  174.     of the arguments, what the function does, and the possible results.
  175.     For efun implementations, this comment should be identical to the
  176.     man page.
  177.  
  178.     Within a function, every variable should be commented as
  179.  
  180.        int foo;  /* short comment */
  181.        int bar;
  182.          /* long comment which doesn't fit on one line.
  183.           */
  184.     
  185.     The major steps in a function should be preceeded by a comment
  186.     explaining them. Also, wherever a critical design decision has
  187.     been made, a comment should line out the whats and whys:
  188.  
  189.         /* Duplicate the stored arguments for the function call.
  190.          * (It's tempting to use the stored arguments directly
  191.          *  in the last pass; however it's not guaranteed that
  192.          *  the last pass actually comes this far.)
  193.          */
  194.  
  195.  
  196.     A typical file layout, commentwise, looks like this:
  197.  
  198.         /*------------------------------------------------------
  199.          * Gamedriver Bouncing module.
  200.          *
  201.          * <reserved for future copyright notice>
  202.          *------------------------------------------------------
  203.          * 'Big picture' description of the module and its
  204.          * relation to the other gamedriver parts.
  205.          *
  206.          * Tricky design discussions also belong in here.
  207.          *------------------------------------------------------
  208.          */
  209.  
  210.         #include "driver.h"
  211.         #include "typedefs.h"
  212.  
  213.         #include <stdlib.h>
  214.  
  215.         #include "bounce.h"
  216.         #include "backend.h"
  217.  
  218.         /*--------------------------------------------------------*/
  219.  
  220.         /* --- User information --- */
  221.         interactive_t *all_bouncers[MAX_PLAYERS];
  222.  
  223.         /* ---  Statistics --- */
  224.  
  225.         p_int number_of_calls;
  226.  
  227.         /*--------------------------------------------------------*/
  228.         void
  229.         add_bouncer (interactive_t *bouncer)
  230.  
  231.         /* This function adds <bouncer> to the all_bouncers[].
  232.          */
  233.         {
  234.             int i;  /* search index */
  235.  
  236.             ....
  237.         } /* add_bouncer() */
  238.  
  239.         /**********************************************************/
  240.  
  241.         
  242.